/**
  ******************************************************************************
  * @file    sym32l010_hal_gpio.c
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   GPIO HAL module driver.
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "sym32l010_hal_gpio.h"


/*******************************************************************************
  * @brief  初始化指定的多个管脚
  * @param  GPIOx     : 端口名称
  *                     @arg SYM_GPIOA
  *                     @arg SYM_GPIOB
  * @param  InitStruct: 初始化结构体
  * @retval None
  * @note   需通过AHBEN寄存器使能GPIOx的时钟后，才可调用该函数
  */
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *InitStruct)
{
    if (InitStruct->Mode == GPIO_MODE_ANALOG)                         // 模拟功能
    {
        REGBITS_SET(GPIOx->ANALOG, InitStruct->Pins);
    }
    else
    {
        REGBITS_CLR(GPIOx->ANALOG, InitStruct->Pins);                 // 数字功能

        if (InitStruct->Pull == GPIO_PULL_UP)                         // 上下拉设置
        {
            REGBITS_SET(GPIOx->PUR, InitStruct->Pins);
        }
        else
        {
            REGBITS_CLR(GPIOx->PUR, InitStruct->Pins);
        }

        if ((InitStruct->Mode & GPIO_MODE_INPUT) == GPIO_MODE_INPUT)  // 输入模式
        {
            REGBITS_SET(GPIOx->DIR, InitStruct->Pins);

            REGBITS_CLR(GPIOx->RISEIE, InitStruct->Pins);
            REGBITS_CLR(GPIOx->FALLIE, InitStruct->Pins);
            if ((InitStruct->IT & GPIO_IT_RISING) == GPIO_IT_RISING)
            {
                REGBITS_SET(GPIOx->RISEIE, InitStruct->Pins);
            }
            if ((InitStruct->IT & GPIO_IT_FALLING) == GPIO_IT_FALLING)
            {
                REGBITS_SET(GPIOx->FALLIE, InitStruct->Pins);
            }
        }

        if ((InitStruct->Mode & GPIO_MODE_OUTPUT_PP) == GPIO_MODE_OUTPUT_PP)    // 输出模式
        {
            if (InitStruct->Mode == GPIO_MODE_OUTPUT_PP)
            {
                REGBITS_CLR(GPIOx->OPENDRAIN, InitStruct->Pins);
            }
            else
            {
                REGBITS_SET(GPIOx->OPENDRAIN, InitStruct->Pins);
            }
            REGBITS_CLR(GPIOx->DIR, InitStruct->Pins);
        }
    }
}


/*******************************************************************************
  * @brief  反初始化指定的多个管脚
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待进行反初始化的端口引脚的集合
  * @retval None
  * @note   需通过AHBEN寄存器使能GPIOx的时钟后，才可调用该函数
  */
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GpioPins)
{
    REGBITS_SET(GPIOx->ANALOG,    GpioPins);
    REGBITS_SET(GPIOx->DIR,       GpioPins);
    REGBITS_CLR(GPIOx->PUR,       GpioPins);
    REGBITS_CLR(GPIOx->RISEIE,    GpioPins);
    REGBITS_CLR(GPIOx->FALLIE,    GpioPins);
    REGBITS_CLR(GPIOx->OPENDRAIN, GpioPins);
    REGBITS_CLR(GPIOx->FILTER,    GpioPins);
}


/*******************************************************************************
  * @brief  获取指定引脚的电平，可获取多个引脚
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待进行读取电平的端口引脚的集合
  * @retval 端口引脚电平
  */
uint16_t HAL_GPIO_ReadPins(GPIO_TypeDef *GPIOx, uint16_t GpioPins)
{
    return (GPIOx->IDR & GpioPins);
}


/*******************************************************************************
  * @brief  获取指定引脚的电平，只获取单个引脚
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待进行读取电平的端口引脚
  * @retval 端口引脚电平
  */
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
    return (((GPIOx->IDR & GPIO_Pin) == (uint32_t)GPIO_PIN_RESET) ? GPIO_PIN_RESET : GPIO_PIN_SET);
}


/*******************************************************************************
  * @brief  采用原子操作，设置指定引脚电平，可设置多个引脚。
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待进行读取电平的端口引脚的集合
  * @param  PinState : @arg GPIO_PIN_RESET 设置管脚为低电平
  *                    @arg GPIO_PIN_SET   设置管脚为高电平
  * @retval None
  */
void HAL_GPIO_WritePins(GPIO_TypeDef *GPIOx, uint16_t GpioPins, GPIO_PinState PinState)
{
    if (PinState == GPIO_PIN_SET)
    {
        GPIOx->BSRR = GpioPins;
    }
    else
    {
        GPIOx->BRR = GpioPins;
    }
}


/*******************************************************************************
  * @brief  采用原子操作，设置端口b0-b7电平值。
  * @param  GPIOx: 端口名称
  *                @arg SYM_GPIOA
  *                @arg SYM_GPIOB
  * @param  Value: 低8bit待输出的电平值
  * @retval None
  */
void HAL_GPIO_LowByte_Write(GPIO_TypeDef *GPIOx, uint8_t Value)
{
    GPIOx->ODRLOWBYTE = Value;
}


/*******************************************************************************
  * @brief  采用原子操作，设置端口b8-b15电平值。
  * @param  GPIOx: 端口名称
  *                @arg SYM_GPIOA
  *                @arg SYM_GPIOB
  * @param  Value: 高8bit待输出的电平值
  * @retval
  * @Note   注意：GPIOA的高8bit只有PA08, GPIOB无高8bit
  */
void HAL_GPIO_HighByte_Write(GPIO_TypeDef *GPIOx, uint8_t Value)
{
    GPIOx->ODRHIGHBYTE = Value;
}


/*******************************************************************************
  * @brief  采用原子操作，对指定引脚电平进行翻转，可设置多个引脚
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待进行翻转电平的端口引脚的集合
  * @retval None
  */
void HAL_GPIO_TogglePins(GPIO_TypeDef *GPIOx, uint16_t GpioPins)
{
    GPIOx->TOG = GpioPins;
}


/*******************************************************************************
  * @brief  配置端口中断滤波
  * @param  GPIOx    : 端口名称
  *                    @arg SYM_GPIOA
  *                    @arg SYM_GPIOB
  * @param  GpioPins : 待配置的端口引脚的集合
  * @param  FltClk   : 滤波时钟
  *                    @arg GPIO_FILTERCLK_HCLK2
  *                    @arg GPIO_FILTERCLK_HCLK4
  *                    @arg GPIO_FILTERCLK_HCLK8
  *                    @arg GPIO_FILTERCLK_BTIM1OV
  *                    @arg GPIO_FILTERCLK_LSI
  *                    @arg GPIO_FILTERCLK_LPTIMOV
  * @retval None
  * @note   DeepSleep模式下，仅 LSI / LPTIM 有效
  */
void HAL_GPIO_IntFilter_Config(GPIO_TypeDef *GPIOx, uint16_t GpioPins, GPIO_FilterClkTypeDef FltClk)
{
    GPIOx->FILTER = FltClk | GpioPins;
}


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
